// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

/*
 * @Author: qiulin_JXGM ql1746365080@gmail.com
 * @Date: 2024-10-23 09:36:37
 * @LastEditors: qiulin ql1746365080@gmail.com
 * @LastEditTime: 2024-12-12 15:15:10
 * @FilePath: \SGFEM\Import\BDFImport\BulkData\Load\PLOAD1Parser.cpp
 */

#include "Import/BDFImport/BulkData/Load/PLOAD1Parser.h"

#include <algorithm>
#include <cstdint>

#include <boost/algorithm/string.hpp>

#include "Utility/Logging/SGLogger.h"

#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Load/IPLOAD1Service.h"

#include "Import/BDFImport/BDFParserBase.h"
BULKDATA_ENTRY_PARSER_REG (PLOAD1);

using namespace SG::DBManager;
using namespace SG::Import;
using namespace SG::DataStructure;
/*
// file://./../../Doc/MarkDown/BulkData/PLOAD1/PLOAD1.md>
*/
// 以下需要修改
enum PLOAD1Key : uint8_t
{
    PLOAD1_SID   = 2,  // Load set identification number. (Integer > 0)
    PLOAD1_EID   = 3,  // Element identification number. (Integer > 0)
    PLOAD1_TYPE  = 4,  // Load type. (Character: "FX", "FY", "FZ", etc.)
    PLOAD1_SCALE = 5,  // Scale factor for X1, X2. (Character: "LE", "FR", etc.)
    PLOAD1_X1    = 6,  // Distance X1 along the element axis. (Real)
    PLOAD1_P1    = 7,  // Load factor at position X1. (Real)
    PLOAD1_X2    = 8,  // Distance X2 along the element axis. (Real, optional)
    PLOAD1_P2    = 9   // Load factor at position X2. (Real, optional)
};

namespace
{
    std::map<std::string, SG::DataStructure::Common::Id> typeMap  = { { "FX", 1 },  { "FY", 2 },   { "FZ", 3 },   { "FXE", 4 },
                                                                      { "FYE", 5 }, { "FZE", 6 },  { "MX", 7 },   { "MY", 8 },
                                                                      { "MZ", 9 },  { "MXE", 10 }, { "MYE", 11 }, { "MZE", 12 } };
    std::map<std::string, SG::DataStructure::Common::Id> scaleMap = { { "LE", 1 }, { "FR", 2 }, { "LEPR", 3 }, { "FRPR", 4 } };
}  // namespace

SG::DataStructure::Common::Status BDF::BULKDATA::ParsePLOAD1 (const std::shared_ptr<SG::DBManager::DBServiceFactory>& dbServiceFactory,
                                                              std::vector<std::string>&                               dividedEntryInfo)
{
    SG::DataStructure::FEM::PLOAD1Data tempdata;

    // TODO(bug 001) m_dominId的正确填写，当前默认domainId设置为1
    tempdata.m_domainId = 1;

    // 当前词条的索引，初始值为1
    int curIDKey = 1;

    // 遍历分割后的词条信息
    for (auto curStrKey : dividedEntryInfo)
    {
        // 检查当前词条是否为空白
        bool const isEmpty = is_all_space (curStrKey);
        if (isEmpty)
        {
            curIDKey++;
            continue;  // 如果是空白，跳过当前词条
        }

        // 将词条转换为科学计数法格式

        // 根据当前词条索引，匹配对应的PLOAD1属性

        switch (curIDKey)
        {
        case PLOAD1_SID:
            // Handle Load set identification number (SID)
            tempdata.m_sId = convertToI64 (curStrKey);
            break;
        case PLOAD1_EID:
            // Handle Element identification number (EID)
            tempdata.m_eId = convertToI64 (curStrKey);
            break;
        case PLOAD1_TYPE:
            // Handle Load per unit surface area at corner 1 (P1)
            boost::trim (curStrKey);
            tempdata.m_type = typeMap[curStrKey];
            break;
        case PLOAD1_SCALE:
            // Handle Load per unit surface area at corner 2 (P2)
            boost::trim (curStrKey);
            tempdata.m_scale = scaleMap[curStrKey];
            break;
        case PLOAD1_X1:
            // Handle Load per unit surface area at corner 3 (P3)
            tempdata.m_x1 = convertToReal (curStrKey);
            break;
        case PLOAD1_P1:
            // Handle Load per unit surface area at corner 4 (P4)
            tempdata.m_p1 = convertToReal (curStrKey);
            break;
        case PLOAD1_X2:
            // Handle Grid point G1
            tempdata.m_x2 = convertToReal (curStrKey);
            break;
        case PLOAD1_P2:
            // Handle Grid point G3 or G4
            tempdata.m_p2 = convertToReal (curStrKey);
            break;
        default:
            // Handle unknown key
            break;
        }

        // 处理完当前词条后，索引递增
        curIDKey++;
    }

    // 将解析好的PLOAD1数据添加到数据库服务

    return dbServiceFactory->get<IPLOAD1Service> ()->Add (tempdata);
}